package com.example.demo.restcontroller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.User;
import com.example.demo.service.UserAuthorityService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;


@CrossOrigin
@RestController

public class UserManagementRestController {

    @Autowired
    UserService userService;

    @Autowired
    UserAuthorityService userAuthorityService;

    @Autowired
    RedisTemplate redisTemplate;

    //testMybatisPlus的分页
    @GetMapping("/testMybatisPlusPage")
    //查询时前端传过来的参数（page:第几页，limit：显示几条数据）
    public Map<String, Object> testMybatisPlusPage(User user, int page, int limit) {
        HashMap<String, Object> map = new HashMap<>();
        //生成一个java的分页对象（传入分页的要求以及形式：第几页？每页几条（从前端来））
        Page<User> producePage = new Page<User>(page, limit);
        //进行调用 返回查询后的分页对象
        Page resultPage = userService.selectUserListByMybatisPlusPage(user, producePage);

//        protected List<T> records;查询到的数据
//        protected long total;总记录条数
//        protected long size;每页显示的条数
//        protected long current;当前页
//        protected boolean searchCount;总条数查询开启

        //总记录条数
        long count = resultPage.getTotal();
        //查询到的数据
        List resultList = resultPage.getRecords();
        if (resultList != null) {
            map.put("code", 0);
            map.put("msg", "用户列表");
            map.put("count", count);
            map.put("data", resultList);
        } else {
            map.put("code", -1);
        }
        return map;
    }


    @GetMapping("/selectUserList")
    //查询时前端传过来的参数（page:第几页，limit：显示几条数据）
    public Map<String, Object> selectUserList(User user, int page, int limit) {
        HashMap<String, Object> map = new HashMap<>();
        //得到其实数据的公式
        int start = (page - 1) * limit;
        //进行封装
        user.setStart(start);
        user.setLimit(limit);
        //根据条件查询出符合的全部记录
        Integer count = userService.getUserListCount(user);
        List<User> userList = userService.selectUserListByPage(user);
        if (userList != null) {
            map.put("code", 0);
            map.put("msg", "用户列表");
            map.put("count", count);
            map.put("data", userList);
        } else {
            map.put("code", -1);
        }
        return map;
    }


    @GetMapping("/selectParentId")
    public Map<String, Object> selectParentId(int parentId) {
        HashMap<String, Object> map = new HashMap<>();
        User user = userService.selectUserByParentId(parentId);
        Integer authorityId = userService.getAuthorityIdByUserId(parentId);
        String authorityName = userService.getAuthorityNameByUserId(parentId);
        user.setAuthorityId(authorityId);
        user.setAuthorityName(authorityName);
        if (user != null) {
            map.put("code", 200);
            map.put("data", user);
        } else {
            map.put("code", -1);
        }
        return map;
    }

    @PostMapping("/insertUser")
    public Map<String, Object> insertUser(User user) {
        HashMap<String, Object> map = new HashMap<>();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(encoder.encode(user.getPassword()));
        user.setId((userService.getUserListCount(null)) + 1);
        if (user.getGender().equals(0)) {
            user.setGender("男");
        } else user.setGender("女");
        int result = userService.insertUserByUser(user);
        int i = userAuthorityService.insertUserAuthorityByUser(user);
        if (result != 0 && i != 0) {
            map.put("code", 200);
        } else map.put("code", -1);
        return map;
    }

    @PostMapping("/updateUser")
    public Map<String, Object> updateUser(User user) {
        HashMap<String, Object> map = new HashMap<>();
        int result = userService.updateUserByUser(user);
        int i = userService.updateUserAuthorityByUser(user);
        if (result != 0 && i != 0) {
            map.put("code", 200);
        } else map.put("code", -1);
        return map;
    }

    @GetMapping("/removeByList")
    public Map<String, Object> removeByList(int[] ids) {
        HashMap<String, Object> map = new HashMap<>();
        int i = userService.removeByList(ids);
        if (i > 0) {
            map.put("code", 200);
        } else map.put("code", -1);
        return map;
    }

    @GetMapping("/removeByListMybatisPlus")
    //虽然前端封装的是int数组 但是in[] 变成Integer[]可以采用自动装箱的操作形式
    //所以可以采用Integer []进行接收数据
    public Map<String, Object> removeByListMybatisPlus(Integer[] ids) {
        HashMap<String, Object> map = new HashMap<>();
        int i = userService.removeByListMybatisPlus(ids);
        if (i > 0) {
            map.put("code", 200);
        } else map.put("code", -1);
        return map;
    }


    @GetMapping("/deleteUser")
    public Map<String, Object> deleteUser(User user) {
        HashMap<String, Object> map = new HashMap<>();
        int result = userService.deleteUserById(user);
        if (result != 0) {
            map.put("code", 200);
        } else map.put("code", -1);
        return map;
    }


    //文件上传页面的from表单提交的地址，与这里保持一致否则提交的东西拿不到
    @PostMapping("/uploadFile")
    //将上传的文件以数组的形式拿到
    //上传的文本框的名字 要与这里定义的参数名字保持一致 否则也拿不到上传的数据（fileUpload）
    public Map<String, Object> uploadFile(MultipartFile file, Integer userId) {
        HashMap<String, Object> map = new HashMap<>();
        //将需要上传的数据以数组的形式进行获取 并且在其中进行操作
//        for (MultipartFile file :
//                fileUpload) {
        //getOriginalFilename() 作用：获取文件的全路径名（例如：E:\备份\【课表】软件3月份课表-胡昆.xlsx）
        String filename = file.getOriginalFilename();
        //lastIndexOf("\\") 作用：拿到需要的部分（非全路径名） 最后一个“/”后的内容（包括“/”）
        //返回值是一个索引
        int index = filename.lastIndexOf("\\");//转义字符
        //substring(index + 1) 作用：拿到需要的部分 拿到以该索引开头到末尾的部分
        filename = filename.substring(index + 1);
        //防止上传文件的过程中发生重名 根据系统自动生成随机数进行定义新的名字
        //UUID.randomUUID() 作用：系统自动生成随机数  再加上文件原来需要的路径 组成新的名字
        filename = UUID.randomUUID() + "_" + filename;
        //定义一个新的文件(全路径名的方式进行定义)
        String dirPath = "/Users/lin/Desktop/upload/";
        //new File(dirPath) 作用：生成一个文件 根据文件的全路径名进行生成
        File filePath = new File(dirPath);
        //判断是否存在该文件
        if (!filePath.exists()) {
            //如果不存在 创建出该文件
            filePath.mkdirs();
        }
        try {
            //transferTo(new File(dirPath + filename)) 作用：将数据传输到指定的文件下
            //生成一个文件（本身没有）对象 将数据放入到该文件（对象）中
            file.transferTo(new File(dirPath + filename));
            User user = new User();
            user.setId(userId);
            user.setAvatar(filename);
            int i = userService.updateUserAvatarByUserId(user);
            map.put("code", i);
            map.put("obj", filename);
        } catch (IOException e) {
            map.put("code", 0);
            e.printStackTrace();
        }
//        }
        return map;
    }


    @PostMapping("/personSubmit")
    public Map<String, Object> personSubmit(User user) {
        HashMap<String, Object> map = new HashMap<>();
        int i = userService.updateUserByUser(user);
        if (i > 0) {
            map.put("code", 200);
            User res = userService.selectUserByParentId(user.getId());
            map.put("data", res);
        } else map.put("code", 0);
        return map;
    }


    //login请求成功后进入的请求
    //也就是在这里返回前台需要的回调函数 默认是get
    @GetMapping("/loginSuccessUrl")
    public Map<String, Object> loginSuccessUrl() {
        HashMap<String, Object> map = new HashMap<>();
        User user = (User) redisTemplate.opsForValue().get("user");
        map.put("code", 200);
        map.put("data", user);
        return map;
    }


    //login请求失败后进入的请求
    //也就是在这里返回前台需要的回调函数 默认是post
    @PostMapping("/loginFailUrl")
    public Map<String, Object> loginFailUrl() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("code", 0);
        return map;
    }

}
